package com.elitedatai.mchtest.manage.service;

import com.dji.sdk.cloudapi.device.ControlSourceEnum;
import com.dji.sdk.cloudapi.device.DeviceOsdHost;
import com.dji.sdk.cloudapi.device.DockModeCodeEnum;
import com.dji.sdk.cloudapi.device.DroneModeCodeEnum;
import com.dji.sdk.common.HttpResultResponse;
import com.dji.sdk.common.PaginationData;
import com.dji.sdk.config.version.GatewayManager;
import com.elitedatai.mchtest.component.websocket.model.BizCodeEnum;
import com.elitedatai.mchtest.manage.model.dto.DeviceDTO;
import com.elitedatai.mchtest.manage.model.dto.DeviceFirmwareUpgradeDTO;
import com.elitedatai.mchtest.manage.model.dto.TopologyDeviceDTO;
import com.elitedatai.mchtest.manage.model.param.DeviceQueryParam;
import com.fasterxml.jackson.databind.JsonNode;
import java.util.List;
import java.util.Optional;


/**
 * 设备服务接口，定义了设备管理相关的业务方法
 */
public interface IDeviceService {

    /**
     * 子设备下线处理
     * @param deviceSn 设备序列号
     */
    void subDeviceOffline(String deviceSn);

    /**
     * 网关设备下线处理
     * @param gatewaySn 网关设备序列号
     */
    void gatewayOffline(String gatewaySn);

    /**
     * 网关设备上线时订阅相关主题，取消订阅子设备主题
     * @param gateway 网关管理器
     */
    void gatewayOnlineSubscribeTopic(GatewayManager gateway);

    /**
     * 无人机上线时订阅网关和子设备的主题
     * @param gateway 网关管理器
     */
    void subDeviceOnlineSubscribeTopic(GatewayManager gateway);

    /**
     * 网关设备下线时取消订阅网关和子设备的主题
     * @param gateway 网关管理器
     */
    void offlineUnsubscribeTopic(GatewayManager gateway);

    /**
     * 根据不同查询条件获取设备数据
     * @param param 查询参数
     * @return 设备列表
     */
    List<DeviceDTO> getDevicesByParams(DeviceQueryParam param);

    /**
     * Web端业务接口，获取工作空间内所有设备的完整信息
     * @param workspaceId 工作空间ID
     * @return 设备列表
     */
    List<DeviceDTO> getDevicesTopoForWeb(String workspaceId);

    /**
     * 设置无人机的遥控器和负载信息
     * @param device 设备DTO对象
     */
    void spliceDeviceTopo(DeviceDTO device);

    /**
     * 根据设备序列号查询设备信息
     * @param sn 设备序列号
     * @return 设备拓扑DTO对象的可选包装
     */
    Optional<TopologyDeviceDTO> getDeviceTopoForPilot(String sn);

    /**
     * 将单个设备信息转换为拓扑对象
     * @param device 设备DTO对象
     * @return 设备拓扑DTO对象
     */
    TopologyDeviceDTO deviceConvertToTopologyDTO(DeviceDTO device);

    /**
     * 当服务器接收到同一工作空间内任何设备上线、下线和拓扑更新的请求时，
     * 也会通过websocket向PILOT广播设备上线、下线和拓扑更新的推送，
     * PILOT在接收到推送后会重新获取设备拓扑列表。
     * @param workspaceId 工作空间ID
     * @param deviceSn 设备序列号
     */
    void pushDeviceOfflineTopo(String workspaceId, String deviceSn);

    /**
     * 当服务器接收到同一工作空间内任何设备上线、下线和拓扑更新的请求时，
     * 也会通过websocket向PILOT广播设备上线、下线和拓扑更新的推送，
     * PILOT在接收到推送后会重新获取设备拓扑列表。
     * @param workspaceId 工作空间ID
     * @param gatewaySn 网关序列号
     * @param deviceSn 设备序列号
     */
    void pushDeviceOnlineTopo(String workspaceId, String gatewaySn, String deviceSn);

    /**
     * 更新设备信息
     * @param deviceDTO 设备DTO对象
     * @return 更新结果
     */
    Boolean updateDevice(DeviceDTO deviceDTO);

    /**
     * 将设备绑定到组织和人员
     * @param device 设备DTO对象
     */
    Boolean bindDevice(DeviceDTO device);

    /**
     * 获取工作空间内已绑定的设备列表
     * @param workspaceId 工作空间ID
     * @param page 页码
     * @param pageSize 每页大小
     * @param domain 域名
     * @return 分页设备数据
     */
    PaginationData<DeviceDTO> getBoundDevicesWithDomain(String workspaceId, Long page, Long pageSize, Integer domain);

    /**
     * 根据设备序列号解绑设备
     * @param deviceSn 设备序列号
     */
    void unbindDevice(String deviceSn);

    /**
     * 根据设备序列号获取设备信息
     * @param sn 设备序列号
     * @return 设备DTO对象的可选包装
     */
    Optional<DeviceDTO> getDeviceBySn(String sn);

    /**
     * 为设备固件更新创建作业
     * @param workspaceId 工作空间ID
     * @param upgradeDTOS 设备固件升级DTO列表
     * @return HTTP响应结果
     */
    HttpResultResponse createDeviceOtaJob(String workspaceId, List<DeviceFirmwareUpgradeDTO> upgradeDTOS);

    /**
     * 设置无人机的属性参数
     * @param workspaceId 工作空间ID
     * @param dockSn 机库序列号
     * @param param 参数JSON节点
     * @return 操作结果代码
     */
    int devicePropertySet(String workspaceId, String dockSn, JsonNode param);

    /**
     * 检查机库的工作状态
     * @param dockSn 机库序列号
     * @return 机库模式代码枚举
     */
    DockModeCodeEnum getDockMode(String dockSn);

    /**
     * 查询无人机的工作状态
     * @param deviceSn 设备序列号
     * @return 无人机模式代码枚举
     */
    DroneModeCodeEnum getDeviceMode(String deviceSn);

    /**
     * 检查机库是否处于DRC模式
     * @param dockSn 机库序列号
     * @return 检查结果
     */
    Boolean checkDockDrcMode(String dockSn);

    /**
     * 检查设备是否具有飞行控制权限
     * @param gatewaySn 网关序列号
     * @return 检查结果
     */
    Boolean checkAuthorityFlight(String gatewaySn);

    /**
     * 保存设备信息
     * @param device 设备DTO对象
     * @return 保存结果代码
     */
    Long saveDevice(DeviceDTO device);

    /**
     * 保存或更新设备信息
     * @param device 设备DTO对象
     * @return 操作结果
     */
    Boolean saveOrUpdateDevice(DeviceDTO device);

    /**
     * 向Pilot推送OSD数据
     * @param workspaceId 工作空间ID
     * @param sn 设备序列号
     * @param data 设备OSD主机数据
     */
    void pushOsdDataToPilot(String workspaceId, String sn, DeviceOsdHost data);

    /**
     * 向Web推送OSD数据
     * @param workspaceId 工作空间ID
     * @param codeEnum 业务代码枚举
     * @param sn 设备序列号
     * @param data 数据对象
     */
    void pushOsdDataToWeb(String workspaceId, BizCodeEnum codeEnum, String sn, Object data);

    /**
     * 更新飞行控制
     * @param gateway 网关设备DTO
     * @param controlSource 控制源枚举
     */
    void updateFlightControl(DeviceDTO gateway, ControlSourceEnum controlSource);
}